<?php defined('SYS_PATH') or die('No direct script access.');
/**
 * Model class
 *
 * @author zendzhang<zendzhang@hotmail.com>
 * @version $Id: Model.php 9 2013-01-14 03:24:50Z zendzhang@hotmail.com $
 */
abstract class TrueBlood_Model extends TrueBlood
{
    /**
     * Master conf
     *
     * @var string
     */
    protected $_master = 'default';

    /**
     * Slave conf
     *
     * @var string
     */
    protected $_slave = 'default';

    /**
     * Table name
     *
     * @var string
     */
    protected $_table = '';

    /**
     * Error levels
     *
     * @var int
     */
    const SYSTEM_ERROR = -1;

    /**
     * Constructor
     */
    public function __construct()
    {
        if (empty($this->_table))
        {
            $this->table(ucfirst(substr(get_class($this), 0, -5)));
        }
    }

    /**
     * Set or get master/slave conf
     *
     * @param string $master
     * @param string $slave
     * @param mixed $
     */
    public function database($master = null, $slave = null)
    {
        if (null === $slave)
        {
            $slave = $master;
        }
        if (null !== $master && null !== $slave)
        {
            $this->_master = $master;
            $this->_slave = $slave;
            return $this;
        }
        return $this->_master . '|' . $this->_slave;
    }

    /**
     * Set or get table name
     *
     * @param string $name
     * @param mixed $
     */
    public function table($name = null)
    {
        if (null !== $name)
        {
            $this->_table = $name;
            return $this;
        }
        return $this->_table;
    }

    /**
     * Get or set error
     *
     * @param mixed $error string|array
     * @return mixed $error string|array
     */
    public function error($error = null)
    {
        if (null !== $error)
        {
            $this->_error = $error;
        }
        return $this->_error;
    }

    /**
     * Select one
     *
     * @param int $id
     * @param string $column
     * @return array
     */
    public function select($id, $column = 'id')
    {
        try
        {
            $sql = "SELECT * FROM $this->_table WHERE {$column} = " . (is_int($id) ? $id : "'$id'");
            $result = $this->slave->row($sql);
            return $result;
        }
        catch (Exception $e)
        {
            $this->error(array('code' => self::SYSTEM_ERROR, 'msg' => $e->getMessage()));
            return false;
        }
    }

    /**
     * Finds results
     *
     * @param mixed $where
     * @param string $order
     * @param string $fields
     * @return array
     */
    public function finds($where, $order = null, $fields = "*")
    {
        try
        {
            $params = array
            (
                'fields' => $fields,
                'table' => $this->_table,
                'where' => $where,
                'order' => $order
            );
            $result = $this->slave->select($params);
            return $result;
        }
        catch (Exception $e)
        {
            $this->error(array('code' => self::SYSTEM_ERROR, 'msg' => $e->getMessage()));
            return false;
        }
    }

    /**
     * Select by page
     *
     * @param mixed $where
     * @param int $total
     * @param array $pages
     * @param string $order
     * @param string $fields
     * @return array
     */
    public function pages($where, &$total, $pages = array(1, 10), $order = null, $fields = "*")
    {
        try
        {
            $result = array();
            $total = $this->slave->count($where, $this->_table);
            if ($total <= 0)
            {
                return $result;
            }
            $params = array
            (
                'fields' => $fields,
                'table' => $this->_table,
                'where' => $where,
                'order' => $order,
                'start' => ($pages[0] - 1) * $pages[1],
                'limit' => $pages[1]
            );
            $result = $this->slave->select($params);
            return $result;
        }
        catch (Exception $e)
        {
            $this->error(array('code' => self::SYSTEM_ERROR, 'msg' => $e->getMessage()));
            return false;
        }
    }

    /**
     * Insert
     *
     * @param array $insert
     * @return bool
     */
    public function insert($insert)
    {
        try
        {
            $result = $this->master->insert($insert, $this->_table);
            return $result;
        }
        catch (Exception $e)
        {
            $this->error(array('code' => self::SYSTEM_ERROR, 'msg' => $e->getMessage()));
            return false;
        }
    }

    /**
     * Update
     *
     * @param array $update
     * @param mixed $where
     * @package bool $formula
     * @return bool
     */
    public function update($update, $where, $formula = false)
    {
        try
        {
            $result = $this->master->update($update, $where, $this->_table, $formula);
            return true;
        }
        catch (Exception $e)
        {
            $this->error(array('code' => self::SYSTEM_ERROR, 'msg' => $e->getMessage()));
            return false;
        }
    }

    /**
     * Delete
     *
     * @param mixed $where
     * @return bool
     */
    public function delete($where)
    {
        try
        {
            $result = $this->master->delete($where, $this->_table);
            return $result;
        }
        catch (Exception $e)
        {
            $this->error(array('code' => self::SYSTEM_ERROR, 'msg' => $e->getMessage()));
            return false;
        }
    }

    /**
     * Count result
     *
     * @param mixed $where
     * @return int
     */
    public function count($where)
    {
        try
        {
            $result = $this->slave->count($where, $this->_table);
            return $result;
        }
        catch (Exception $e)
        {
            $this->error(array('code' => self::SYSTEM_ERROR, 'msg' => $e->getMessage()));
            return false;
        }
    }

    /**
     * Get SQL result
     *
     * @param string $sql
     * @return mixed
     */
    public function sql($sql)
    {
        try
        {
            $expr = strtoupper(current(explode(' ', $sql)));
            $result = 'SELECT' === $expr ? $this->slave->sql($sql) : $this->master->sql($sql);
            return $result;
        }
        catch (Exception $e)
        {
            $this->error(array('code' => self::SYSTEM_ERROR, 'msg' => $e->getMessage()));
            return false;
        }
    }

    /**
     * Dynamic get vars
     *
     * @param string $key
     */
    public function __get($key)
    {
        switch ($key)
        {
            case 'master':
                return $this->master = $this->load->database($this->_master);
            case 'slave' :
                return $this->slave = $this->load->database($this->_slave);
            default:
                return parent::__get($key);
        }
    }
}

?>